package com.quanyan.ic.task.job;

import com.alibaba.fastjson.JSON;
import com.github.ltsopensource.core.domain.Action;
import com.github.ltsopensource.tasktracker.Result;
import com.github.ltsopensource.tasktracker.runner.JobContext;
import com.github.ltsopensource.tasktracker.runner.JobRunner;
import com.quanyan.ic.cache.OrderMsgDao;
import com.quanyan.ic.cache.PlaceLightSettingDao;
import com.quanyan.ic.common.model.OrderMessage;
import com.quanyan.ic.constants.OrderConstant;
import com.quanyan.ic.model.FailedOrderMessage;
import com.quanyan.ic.model.PlaceLightSetting;
import com.quanyan.ic.protocol.LightCmd;
import com.quanyan.ic.protocol.codec.protobuf.ICMessageBuilder;
import com.quanyan.ic.protocol.server.LightServer;
import io.netty.channel.Channel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * Created by zhuo.shi on 2017/6/2.
 */
@Component
public class SendICMessageJob implements JobRunner {

    private static Logger logger = LoggerFactory.getLogger(SendICMessageJob.class);

    @Autowired
    private PlaceLightSettingDao placeLightSettingDao;
    @Autowired
    private OrderMsgDao orderMsgDao;

    @Override
    public Result run(JobContext jobContext) throws Throwable {

        String taskId = jobContext.getJob().getTaskId();
        Map<String, String> param = jobContext.getJob().getExtParams();
        OrderMessage orderMessage = JSON.parseObject(param.get("orderMsg"), OrderMessage.class);
        Integer pid = orderMessage.getPlaceId();
        Integer sid = orderMessage.getSiteId();
        Integer lcmd = Integer.valueOf(param.get("lcmd"));
        logger.info("execute job：taskId={}, param={}", taskId, param);

        //查找到写消息的Channel
        Channel channel = LightServer.getSessionChannelMap().get(String.valueOf(pid));

        //查找 orderMsg
        OrderMessage _orderMessage = orderMsgDao.findOrderMsg(orderMessage);
        if (_orderMessage == null) {
            logger.warn("can't find the orderMsg [{}] from cache, return", taskId);
            return new Result(Action.EXECUTE_FAILED);
        }

        if (channel == null || !channel.isActive()) {
            //记录
            logger.warn("taskId={}, channel already closed, may be the the client is down, record the orderMsg to failed cache queue!", taskId);
            orderMsgDao.saveFailedChannelMsg(FailedOrderMessage.build(orderMessage, lcmd == 0 ? LightCmd.OFF : LightCmd.ON));
            return new Result(Action.EXECUTE_SUCCESS);
        }

        PlaceLightSetting setting = placeLightSettingDao.getLightControlSetting(pid);
        long before = setting.getOn_light_before_order_start() * 60 * 1000;
        long after = setting.getOff_light_after_order_end() * 60 * 1000;

        if (lcmd == LightCmd.ON.value()) {
//            if (orderMsgDao.isOrderTimeSegmentIncludeBuffer(pid, sid, before, after)) {  //并且此场地当前时间有订单
            sendCmd(channel, orderMessage, LightCmd.ON);
            logger.info("send ON cmd to client {}, success, taskId={}", channel.remoteAddress(), taskId);
//            }else {
//                logger.info("current time, the place {} site {} haven't order time segment, don't sent ON cmd to client", pid, sid);
//            }
        }
        if (lcmd == LightCmd.OFF.value()) {
            boolean hasOrderTimeSegment = orderMsgDao.isOrderTimeSegmentIncludeBuffer(pid, sid, before, after);
            if (!hasOrderTimeSegment        //当前时间段内没有订单，并且此关灯指令不是由于退款下发的
                    && orderMessage.getOrderStatus() != OrderConstant.ORDER_STATUS_REFUND) {
                sendCmd(channel, orderMessage, LightCmd.OFF);
                logger.info("send OFF cmd to client {}, success, taskId={}", channel.remoteAddress(), taskId);
            } else {
                logger.info("current time, the place {} site {} have order time segment, don't sent OFF cmd to client", pid, sid);
            }
        }

        return new Result(Action.EXECUTE_FAILED);
    }

    private void sendCmd(Channel channel, OrderMessage orderMessage, LightCmd cmd) {
        channel.writeAndFlush(ICMessageBuilder.buildBizICMessage(orderMessage, cmd));
        orderMsgDao.saveFailedChannelMsg(FailedOrderMessage.build(orderMessage, cmd));
    }
}
